package receiveFile

import (
	"bufio"
	"fmt"
	"github.com/russross/blackfriday"
	"kd_rewiew/storage"
	"os"
	"strings"
)

const basePlace = "/home/hufeng/GolandProjects/hufeng_review"

// ParseMd 该部分进行输入的md文件的处理，进行解析并调用外部api进行处理
func ParseMd(file string) error {
	bytes, err := os.Open(fmt.Sprintf("%s/receiveFile/%s", basePlace, file))
	if err != nil {
		return err
	}
	//basic := blackfriday.MarkdownBasic(bytes)
	scanner := bufio.NewScanner(bytes)
	for scanner.Scan() {
		basic := blackfriday.MarkdownBasic(scanner.Bytes())
		fmt.Println(string(basic), "---", string(scanner.Bytes()))
		if strings.HasPrefix(string(basic), "<h6>") {
		}
	}
	return nil
}

// 这个库还实现了md语法解析，将其可以简单实现为html文件格式内容
var preString = []string{"[title]", "[keywords]", "[creator]", "[content]"}

/*
任务
1.完成文章内容解析
2.进行内容存储
3.进行关键字存储
4.进行文章和关键字关联
*/

func ParseDoc(file string) error {
	bytes, err := os.Open(fmt.Sprintf("%s/receiveFile/%s", basePlace, file))
	if err != nil {
		return fmt.Errorf("error on open : %v", err)
	}
	scanner := bufio.NewScanner(bytes)
	article := &storage.Article{}
	keywords := storage.Keywords{}
	articleKeyword := &storage.ArticleKeyword{}
	for scanner.Scan() {
		prefix, _ := GetPrefix(scanner.Text())
		if strings.Contains(strings.Join(preString, ","), prefix) {
			//fmt.Println(GetPrefix(scanner.Text()))
			getPrefix, s := GetPrefix(scanner.Text())
			switch getPrefix {
			case "[title]":
				//fmt.Println(s)
				article.Title = s
			case "[keywords]":
				//fmt.Println(s)
				split := strings.Split(s, ",")
				keywords.Words = split
				//fmt.Println(s, "--", split)
				article.Keywords = s
				//fmt.Println(split)
			case "[creator]":
				//fmt.Println(s)
				article.Creator = s
			case "[content]":
				//fmt.Println(s)
				article.Content = s
			}
		} else {
			// 剩余的不包含前缀的就是正文部分
			article.Content += scanner.Text()
		}
	}
	//fmt.Println("article and keywords: ", article, keywords)
	// 此时包含多个关键字，我们进行关键字的拆分，多次添加，但是这样会增加开销
	wordsData, err := storage.GetTableLink("Keywords")
	if err != nil {
		return err
	}
	fmt.Println("wordsData: ", wordsData)
	for _, x := range keywords.Words {
		word := storage.Keyword{Word: x}
		// 还是要进行判断关键字是否存在，如果存在不进行关键字的存储，但是如果存在文章不同，但是关键字相同还是要进行存储A-K表
		//fmt.Println("word: ", word)
		//fmt.Println("wordsData: ", wordsData)
		// 这一步使用数据库引擎？使用这个方式在数据量比较大的情况下，会消耗很大，一直查询
		if notInKeywords(x, wordsData) {
			if err = storage.AddTableLine("Keywords", word); err != nil {
				return err
			}
		} else {
			fmt.Println("keywords always inner the data")
			break
		}
		// 本循环已完成关键字的插入和避免重复，下面是为了实现关联表的插入，其实添加包含外检约束的数据一样的，就是在添加的时候表会判断数据是否在另外两张表中存在，存在才会进行存储
	}
	//完成解析之后还要进行判断之前是否存在，进行表查询，然后再存储
	articleData, err := storage.GetTableLink("Articles")
	if err != nil {
		return err
	}
	fmt.Println("articleData: ", articleData)
	if !notInArticles(article.Title, articleData) {
		fmt.Printf("error on add current article: %s\n", article.Title)
	} else {
		fmt.Println("文章不存在于数据库")
		//fmt.Println(storage.GetMsg(article))
		//然后就是进行存储到表中了
		if err = storage.AddTableLine("Articles", article); err != nil {
			return fmt.Errorf("error on add : %v", err)
		}
		newArticlesData, err := storage.GetTableLink("Articles")
		if err != nil {
			return err
		}
		for _, a := range newArticlesData {
			if a["TITLE"] == article.Title {
				fmt.Println(a["ArticleID"].(int64))
				articleKeyword.ArticleID = a["ArticleID"].(int64)
			}
		}
		for _, x := range keywords.Words {
			// 进行关键字和文章关联表的添加，属于是多对多的存储，要符合参数要求，从之前的数据中取
			for _, k := range wordsData {
				if k["Keyword"] == x {
					articleKeyword.KeywordID = k["KeywordID"].(int64) // 使用断言获取any类型的具体值
				}
			}
		}
		err = storage.AddTableLine("ArticlesKeywords", articleKeyword)
		if err != nil {
			return err
		}
	}
	// 测试期间不进行存储

	return nil
}

func notInArticles(title string, data []map[string]any) bool {
	for _, x := range data {
		fmt.Println("database title: ", "-", x["TITLE"], "-", title)
		if x["TITLE"] == title {
			return false
		}
	}
	return true
}

func notInKeywords(title string, data []map[string]any) bool {
	for _, x := range data {
		fmt.Println("database keyword: ", "-", x["Keyword"], "-", title)
		if x["Keyword"] == title {
			return false
		}
	}
	return true
}

func GetPrefix(s string) (string, string) {
	p := 0
	for i, x := range s {
		if string(x) == "]" {
			p = i
			break
		}
	}
	// fmt.Println(p, s[:p+1], s[p+1:])
	return s[:p+1], s[p+1:]
}
